package it.polimi.swimv2.session;

import it.polimi.swimv2.entities.Ability;
import it.polimi.swimv2.entities.User;
import it.polimi.swimv2.exception.AbilityExistsException;
import it.polimi.swimv2.exception.ModifyException;
import it.polimi.swimv2.remote.AbilityManagerRemote;

import java.util.Collection;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * Session Bean implementation class AbilityManager
 */
@Stateless
public class AbilityManager implements AbilityManagerRemote {
	
	@PersistenceContext(unitName = "swimv2")
	private EntityManager em;

	@EJB private FeedbackManagerLocal feedbackManager;
	
	@EJB private HelpRequestManagerLocal helpRequestManager;
	
	/**
	 * Default constructor.
	 */
	public AbilityManager() {

	}

	@SuppressWarnings("unchecked")
	@Override
	public Collection<String> getDeclarableAbilities() {

		Query q = em.createQuery("SELECT a.name FROM Ability a");
		
		return q.getResultList();
	}

	@Override
	public boolean createNewDeclarableAbility(String abilityName) throws ModifyException, AbilityExistsException {
		if(abilityName==null||abilityName.length()==0){
			throw new ModifyException();
		}
		if(em.find(Ability.class, abilityName)!=null){
			throw new AbilityExistsException();
		}
		Ability newAbility= new Ability(abilityName);
		em.persist(newAbility);
		return true;
	}

	@Override
	public boolean deleteDeclarableAbility(String abilityName) {
		
		Ability a=em.find(Ability.class, abilityName);
		if(a==null)return false;
		helpRequestManager.removeHelpRequests(a);
		feedbackManager.deleteFeedback(a);
		deleteAbilityDeclaration(a);
		deleteAbility(a);
		em.flush();
		return true;
	}

	private void deleteAbility(Ability a) {
		em.remove(a);
		
	}

	private void deleteAbilityDeclaration(Ability a) {
		
		Query q=em.createQuery("SELECT OBJECT(u) "
		+ "FROM User u, IN(u.declaredAbilities) a "
		+ "WHERE a = :ab");
		q.setParameter("ab", a);
		
		@SuppressWarnings("unchecked")
		List<User> users=q.getResultList();
		for(User u:users){
			u.removeAbility(a);
		}
		
	}

	

}
